// Copyright 2010 Google Inc. All Rights Reserved.

package com.google.android.apps.wakemewhere;

import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.util.Log;

import com.google.android.apps.wakemewhere.ui.AlarmFireActivity;

/**
 * @author baran@google.com (Baran Ozgul)
 * 
 */
public class ProximityIntentReceiver extends BroadcastReceiver {

	private static final String LATITUDE_KEY = "LATITUDE_KEY";
	private static final String LONGITUDE_KEY = "LONGITUDE_KEY";
	private LocationManager locationManager;
	private Context context;

	@Override
	public void onReceive(Context context, Intent intent) {	

		this.context = context;
		this.locationManager = (LocationManager) context
				.getSystemService(Context.LOCATION_SERVICE);

		String enteringKey = LocationManager.KEY_PROXIMITY_ENTERING;
		Boolean entering = intent.getBooleanExtra(enteringKey, false);

		// TODO(baran): Do something if the alarm is still -1.
		long alarmId = intent.getLongExtra(IntentExtras.ALARM_ID, -1L);
		Alarm alarm = Alarms.getAlarm(context.getContentResolver(), alarmId);

		if (alarm == null) {
			// Alarm no longer exists delete this pending intent.
			ProximityAlertAlarmArbiter arbiter = new ProximityAlertAlarmArbiter(
					context);
			arbiter.removeProximityAlertForAlarm(context, alarmId);
			return;
		}

		Location currentLocation = getLastKnownLocation();
		Log.i("WAKEMEWHERE",
				"Last known location is " 
				+ currentLocation.getLatitude() + " " + currentLocation.getLongitude());
		if (entering) {
			Location previousLocation = retrieveLastKnownLocationFromPreferences();
			if (previousLocation != null
					&& previousLocation.distanceTo(currentLocation) < ProximityAlertAlarmArbiter.DEFAULT_PROXIMITY_RADIUS) {
				Log.i("WAKEMEWHERE",
						"Haven't moved out of the previous location yet, not firing:"
						+ alarm.getLocationSummary());
				return;
				
			}
			Log.i("WAKEMEWHERE", "Received event: entering:"
					+ alarm.getLocationSummary());
			Intent alarmFireActivity = new Intent(context,
					AlarmFireActivity.class);
			alarmFireActivity.putExtra(IntentExtras.ALARM_ID, alarmId);
			alarmFireActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			context.startActivity(alarmFireActivity);
		} else { // exiting
			Log.i("WAKEMEWHERE", "Received event: exiting:"
					+ alarm.getLocationSummary());
		}

		currentLocation = getLastKnownLocation();
		saveLastKnownCoordinatesInPreferences((float) currentLocation
				.getLatitude(), (float) currentLocation.getLongitude());
		Log.i("WAKEMEWHERE",
				"Last known location is " 
				+ currentLocation.getLatitude() + " " + currentLocation.getLongitude());

	}

	private void saveLastKnownCoordinatesInPreferences(float latitude,
			float longitude) {
		SharedPreferences prefs = context.getSharedPreferences(getClass()
				.getSimpleName(), Context.MODE_PRIVATE);
		SharedPreferences.Editor prefsEditor = prefs.edit();
		prefsEditor.putFloat(LATITUDE_KEY, latitude);
		prefsEditor.putFloat(LONGITUDE_KEY, longitude);
		prefsEditor.commit();
	}

	private Location retrieveLastKnownLocationFromPreferences() {
		SharedPreferences prefs = context.getSharedPreferences(getClass()
				.getSimpleName(), Context.MODE_PRIVATE);
		if (prefs.contains(LATITUDE_KEY) && prefs.contains(LONGITUDE_KEY)) {
			Location location = new Location("POINT_LOCATION");
			location.setLatitude(prefs.getFloat(LATITUDE_KEY, -1000));
			location.setLongitude(prefs.getFloat(LONGITUDE_KEY, -1000));
			return location;
		}
		return null;
	}

	private Location getLastKnownLocation() {
		Location location = locationManager
				.getLastKnownLocation(LocationManager.GPS_PROVIDER);
		if (location == null) {
			location = locationManager
					.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
		}
		return location;
	}

	private void saveAlarm(Context context, Alarm alarm) {
		ContentValues values = new ContentValues();
		alarm.writeOnto(values);
		context.getContentResolver().update(Alarms.uriForId(alarm.getId()),
				values, null, null);
	}
}